/*
 * lexervalue.c
 *
 *  Created on: 2013-5-9
 *      Author: xkaying
 */

#include "lexer.h"
#include "lexerpackage.h"
#include "lexervalue.h"

#include "../typedef/token.h"

#include <assert.h>
#include <stdio.h>

char *LexerValue(char *ch, int *line, int *len, Lexer *plex, int size)
{
	assert(ch);
	assert(line);
	assert(len);
	assert(plex);
	int state;
	state = 0;
	Token *ptoken;
	ptoken = 0;
	while ((*len) < size) {
		switch (state)
		{
			case 0: {
				//注释
				switch (*ch)
				{
					//注释单行
					case '0': {
						state = 2;
						ptoken = TokenInit(TokenType_Oct);
						ptoken->str = ch;
						ptoken->len++;
						ptoken->line = *line;
						(*len)++;
						ch++;
						continue;
					}
					default: {
						if ((*ch) >= '1' && (*ch) <= '9') {
							ptoken = TokenInit(TokenType_Decimal);
							ptoken->str = ch;
							ptoken->len++;
							ptoken->line = *line;
							state = 1;
							(*len)++;
							ch++;
							continue;
						}
						return ch;
					}
				}
				printf("错误的lexer comment状态机.状态:0\n");
				return 0;
			}
			case 1: {
				switch (*ch)
				{
					//注释单行
					case '.': {
						//进入浮点数后排读取
						ptoken->type = TokenType_Float;
						state = 10;
						ptoken->len++;
						(*len)++;
						ch++;
						continue;
					}
					default: {
						if ((*ch) >= '0' && (*ch) <= '9') {
							ptoken->len++;
							(*len)++;
							ch++;
							continue;
						}
						if (((*ch >= 'a') && ((*ch) <= 'z'))
								|| ((*ch >= 'A') && ((*ch) <= 'Z'))
								|| ((*ch) == '_')) {
							//表示错误
							printf("第%d行:错误的数值或变量名表达.\n", ptoken->line);
							return 0;
						}
						//不是数字,表示读取结束
						ptoken->name = SymbolTablePush(ptoken->str,
								ptoken->len);
						LexerPush(plex, ptoken);
						ptoken = 0;
						return ch;
					}
				}
				printf("错误的lexer comment状态机.状态:1\n");
				return 0;
			}
			case 2: {
				switch (*ch)
				{
					case '.': {
						state = 10;
						ptoken->type = TokenType_Float;
						(*len)++;
						ch++;
						ptoken->len++;
						continue;
					}
					case 'x':
					case 'X': {
						//16进制
						state = 20;
						ptoken->type = TokenType_Hex;
						(*len)++;
						ch++;
						ptoken->str=ch;
						ptoken->len=0;
						continue;
					}
					case '8':
					case '9': {
						printf("第%d行:以0开始的数值表示8进制数,其数字范围是0-7.\n", ptoken->line);
						return 0;
					}
					default: {
						if ((*ch) >= '0' && (*ch) <= '7') {
							state = 21;
							ptoken->len++;
							(*len)++;
							ch++;
							continue;
						}
						if (((*ch >= 'a') && ((*ch) <= 'z'))
								|| ((*ch >= 'A') && ((*ch) <= 'Z'))
								|| ((*ch) == '_')) {
							//表示错误
							printf("第%d行:错误的数值或变量名表达.\n", ptoken->line);
							return 0;
						}
						//不是数字,表示读取结束
						ptoken->name = SymbolTablePush(ptoken->str,
								ptoken->len);
						LexerPush(plex, ptoken);
						ptoken = 0;
						return ch;
					}
				}
				printf("错误的lexer value状态机.状态:2\n");
				return 0;
			}
			case 10: {
				if ((*ch) >= '0' && (*ch) <= '9') {
					ptoken->len++;
					(*len)++;
					ch++;
					continue;
				}
				if (((*ch >= 'a') && ((*ch) <= 'z'))
						|| ((*ch >= 'A') && ((*ch) <= 'Z')) || ((*ch) == '_')) {
					//表示错误
					printf("第%d行:错误的数值或变量名表达.\n", ptoken->line);
					return 0;
				}
				//不是数字,表示读取结束
				ptoken->name = SymbolTablePush(ptoken->str, ptoken->len);
				LexerPush(plex, ptoken);
				ptoken = 0;
				return ch;
			}
			case 20: {
				if ((*ch) >= '0' && (*ch) <= '9') {
					ptoken->len++;
					(*len)++;
					ch++;
					continue;
				}
				if (((*ch >= 'a') && ((*ch) <= 'f'))
						|| ((*ch >= 'A') && ((*ch) <= 'F'))) {
					ptoken->len++;
					(*len)++;
					ch++;
					continue;
				}
				if (((*ch >= 'g') && ((*ch) <= 'z'))
						|| ((*ch >= 'G') && ((*ch) <= 'Z')) || ((*ch) == '_')) {
					//表示错误
					printf("第%d行:错误的数值或变量名表达.\n", ptoken->line);
					return 0;
				}
				//不是数字,表示读取结束
				ptoken->name = SymbolTablePush(ptoken->str, ptoken->len);
				LexerPush(plex, ptoken);
				ptoken = 0;
				return ch;
			}
			case 21: {
				if ((*ch) >= '0' && (*ch) <= '7') {
					ptoken->len++;
					(*len)++;
					ch++;
					continue;
				}
				if ((*ch) == 8 || (*ch) == 9) {
					printf("第%d行:以0开始的数值表示8进制数,其数字范围是0-7.\n", ptoken->line);
					return 0;
				}
				if (((*ch >= 'a') && ((*ch) <= 'z'))
						|| ((*ch >= 'A') && ((*ch) <= 'Z')) || ((*ch) == '_')) {
					//表示错误
					printf("第%d行:错误的数值或变量名表达.\n", ptoken->line);
					return 0;
				}
				//不是数字,表示读取结束
				ptoken->name = SymbolTablePush(ptoken->str, ptoken->len);
				LexerPush(plex, ptoken);
				ptoken = 0;
				return ch;
			}
			default: {
				printf("错误的lexer value状态机.\n");
				return 0;
			}

		}

	}
	if (ptoken == 0) {
		return ch;
	}
	ptoken->name = SymbolTablePush(ptoken->str, ptoken->len);
	LexerPush(plex, ptoken);
	ptoken = 0;
	return ch;
}
